﻿using System;
using System.ComponentModel.Composition;
using CommonServiceLocator.SpringAdapter;
using Microsoft.Practices.ServiceLocation;
using Reactor.Configuration;
using Reactor.Contracts;
using Reactor.Environment;
using Spring.Context;
using Spring.Context.Support;

namespace Reactor.Container.Spring
{
    [Export(typeof(ICustomizeReactorInitialization))]
    public class ContainerCustomizer : ICustomizeReactorInitialization
    {
        private readonly IApplicationContext _applicationContext;
        private IServiceLocator _serviceLocator;

        /// <summary>
        /// Initializes a new instance of the <see cref="ContainerCustomizer"/> class.
        /// </summary>
        public ContainerCustomizer() : this(new GenericApplicationContext()) {}

        /// <summary>
        /// Initializes a new instance of the <see cref="ContainerCustomizer"/> class.
        /// </summary>
        /// <param name="applicationContext">The application context.</param>
        public ContainerCustomizer(IApplicationContext applicationContext)
        {
            if (applicationContext == null) throw new ArgumentNullException("applicationContext");

            _applicationContext = applicationContext;
        }

        #region Implementation of ICustomizeReactorInitialization

        /// <summary>
        /// Gets the execution order for this initializer. The lower the value, the earlier it will 
        /// be executed in a chain of initializers.
        /// </summary>
        /// <value>The execution order.</value>
        public uint ExecutionOrder
        {
            get { return 0; }
        }

        /// <summary>
        /// Initializes Reactor by providing a Windsor based <seealso cref="IServiceRegistrar"/> and <seealso cref="IServiceLocator"/>.
        /// </summary>
        public void InitializeReactor()
        {
            var springRegistrar = new SpringServiceRegistrar((GenericApplicationContext)_applicationContext);

            // Set platform service locator
            if (_serviceLocator == null) _serviceLocator = new SpringServiceLocatorAdapter(_applicationContext);
            Context.ServiceLocator = _serviceLocator;

            springRegistrar.RegisterInstance<IServiceRegistrar>(springRegistrar);
        }

        #endregion
    }
}
